/*
 * Copyright (c) 2017, www.zm0618.com All Rights Reserved..
 */

package com.light.hessian.remoting.client.core;

import com.light.hessian.remoting.client.balance.Balance;
import com.light.hessian.provider.config.HessianProviderInfo;
import com.light.hessian.provider.slot.ProviderStatusSlot;
import com.light.hessian.provider.slot.ProviderStatusSlotPiple;
import com.light.hessian.remoting.client.config.ClientConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.factory.FactoryBean;

import java.net.MalformedURLException;

/**
 * Created by zhaojun on 2017/02/10.
 */
public class HessianClientProxyFactory extends HessianClientInterceptor implements FactoryBean<Object> {

    protected static final Logger logger= LoggerFactory.getLogger(HessianClientProxyFactory.class);
    private Object serviceProxy;

    @Override
    public void afterPropertiesSet() {
        super.afterPropertiesSet();
        this.serviceProxy = new ProxyFactory(getServiceInterface(), this).getProxy(getBeanClassLoader());
    }
    @Override
    public Object getObject() throws Exception {
        return serviceProxy;
    }

    @Override
    public Class<?> getObjectType() {
        return getServiceInterface();
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    @Override
    protected ProxyObjHolder loadLazyProxyObjHolder(ProviderStatusSlotPiple slotPiple, Balance balance) throws MalformedURLException {
        ProviderStatusSlot statusSlot= slotPiple.pullStatusSlot(balance,this.getReference());
        HessianProviderInfo providerInfo = (HessianProviderInfo) statusSlot.getBaseProviderInfo();
        //通过负载均衡选出服务节点
        String serviceUrl=providerInfo.getServiceUrl();
        //获取对应节点是否有访问节点
        ProxyObjHolder proxyObjHolder = this.proxyObjHolderCache.get(serviceUrl);

        if (proxyObjHolder==null){
            synchronized (HessianClientInterceptor.class){
                if (proxyObjHolder==null){
                    Object proxyObject=createProxyObject(serviceUrl);
                    proxyObjHolder=new ProxyObjHolder();
                    proxyObjHolder.setProxyObj(proxyObject);
                    proxyObjHolder.setProviderInfo(providerInfo);
                    proxyObjHolderCache.put(serviceUrl,proxyObjHolder);
                }
            }
        }
        return proxyObjHolder;

    }

    protected Object createProxyObject(String serviceUrl) throws MalformedURLException {
        ClientConfig clientConfig=new ClientConfig();
        clientConfig.setHost(serviceUrl);
        ProxyObjectBuilder proxyObjectBuilder=new ProxyObjectBuilder(clientConfig,getServiceInterface(),getServiceName());
        Object proxyObject = proxyObjectBuilder.build();
        return proxyObject;
    }

}
